I have a multiple window Mac Catalyst app. I'm using a NSToolbar and the menu bar via UIMenuBuilder.
I noticed after changing windows the menu bar isn't always validating properly. For example my app implements "Undo" and "redo". So I can reproduce the issue using these steps:
Perform an action that can be undone.
Open a new window. This new window has its own undo manager.
In the Menu bar select Edit -> Undo
Undo validates even though the current window has nothing on its local undo stack. If invoked undo is performed on the inactive window which definitely seems wrong.
The same thing sometimes happens in reverse (that is, undo doesn't validate when it should after switching windows). This also happens with other actions after switching windows.
Sometimes I can get the actions to validate by hitting the Tab key to move focus then shift tabbing back, which seems to force proper lookup in the responder chain (but sometimes that doesn't work).
It seems that Catalyst is losing track of the real active window/window scene for some reason and is validating actions on the wrong window scene.
Anyone experience this and know where I could be going wrong and/or know of a possible workaround?
I tried subclassing UIApplication and implementing the methods there (and then forwarding them to the active UIWindowScene). However this doesn't work, the wrong window scene has its activationState set to UISceneActivationStateForegroundActive when the problem occurs.
Post
Replies
Boosts
Views
Activity
I'm trying to create a dynamic menu on Mac Catalyst. Using a UIBarButtonitem like so to make a "pull down" button:
UIDeferredMenuElement *deferredmenuElement;
deferredmenuElement = [UIDeferredMenuElement elementWithUncachedProvider:^(void (^ _Nonnull completion)(NSArray<UIMenuElement *> * _Nonnull))
{
UIAction *actionOne = [UIAction actionWithTitle:@"Action One" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
NSLog(@"action one fired.");
}];
UIAction *actionTwo = [UIAction actionWithTitle:@"Action Two" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
NSLog(@"action two fired.");
}];
UIAction *actionThree = [UIAction actionWithTitle:@"Action Three" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
NSLog(@"action three fired.");
}];
completion(@[actionOne,actionTwo,actionThree]);
}];
UIMenu *wrappedMenu = [UIMenu menuWithChildren:@[deferredmenuElement]];
UIBarButtonItem *uiBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:nil
menu:wrappedMenu];
uiBarButtonItem.image = [UIImage systemImageNamed:@"rectangle.and.pencil.and.ellipsis"];
self.navigationItem.rightBarButtonItems = @[uiBarButtonItem];
The button appears in the toolbar but when I click it to expose the menu I get a menu with on element in it that says "Loading...". The the uncached provider block is never called.
Running Ventura 13.2.1 and Xcode 14.2.
I have a UISearchController. It uses a search results controller (the search results controller uses a UITableView). If I select a row.. scroll a bit, deactivate the window then reactivate the window the scroll position starts flying. Usually this random scroll exposes the selected row but sometimes it scroll elsewhere.
I subclassed UITableView to try to figure out what's causing this random scrolling. I have a breakpoint in -scrollRectToVisible:scrollRectToVisible:
-(void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
{
[super scrollRectToVisible:rect animated:animated]; //<--Break point here
}
And was able to determine that its coming from UIFocusSystem/UISearchController:
#1 0x00000001d65d748c in -[UISearchController _willUpdateFocusInContext:withAnimationCoordinator:] ()
#2 0x00000001d611fdd0 in __85-[UIFocusSystem _sendWillUpdateFocusNotificationsInContext:withAnimationCoordinator:]_block_invoke ()
#3 0x00000001d60d4944 in _UIFocusEnvironmentEnumerateAncestorEnvironments ()
#4 0x00000001d6120480 in -[UIFocusSystem _sendNotificationsForFocusUpdateInContext:withAnimationCoordinator:usingBlock:] ()
#5 0x00000001d611faf8 in -[UIFocusSystem _sendWillUpdateFocusNotificationsInContext:withAnimationCoordinator:] ()
#6 0x00000001d611f42c in -[UIFocusSystem _updateFocusWithContext:report:] ()
#7 0x00000001d611b90c in -[UIFocusSystem _setEnabled:withAnimationCoordinator:] ()
#8 0x00000001d61a1128 in __49-[_UIFocusSystemSceneComponent _setupFocusSystem]_block_invoke ()
#9 0x00000001d618ccac in -[_UIFocusStateObserver notifyObserversIfNecessary] ()
--
Workarounds/input always appreciated.
I wasn't able to find an answer to this question via search but I was wondering if it is possible to virtualize an Intel Mac using the Virtualization framework on macOS?
I have an M1 MacBook Pro and I want to virtualize macOS as if it is running on a Mac with an Intel processor.
So I copy a link to the pasteboard in Mac Catalyst. I can do this directly or by using system provided "Copy" in WKWebView from the WebUIDelegate method -webView:contextMenuForElement:willCommitWithAnimator: (which creates a "Copy Link action in the system provided "suggested actions").
So when I copy a link on Mac Catalyst like this:
[UIPasteboard generalPasteboard].URLs = @[urlToCopy];
And I try to paste it in Xcode (assuming I'd be pasting the URL string in this context) Xcode plays NSBeep and nothing is pasted. I have to paste the link in TextEdit in a Plain Text Document, select the text, copy it again and then paste it back in Xcode.
I'm having a pretty bad day here. Almost nothing is working.
I set the elementFullscreenEnabled property on WKPreferences to YES. On iPad this enables web videos to be played in full screen.
However when I play the video and rotate the device, the layout becomes completely broken on orientation change. Anyone know of a workaround?
I can key value observe the web view's full screen state property but there is no obvious way to get ahold of the UI being used to play the video?
I notice on some pages to be having text selection issues on Mac Catalyst. AppKit WKWebview appears to work better. Is there a workaround?
Related:
https://stackoverflow.com/questions/74959180/how-to-use-appkit-wkwebview-in-a-mac-catalyst-app
https://stackoverflow.com/questions/61215569/macos-maccatalyst-wkwebview-text-selection-behavior
Would be great if Mac Catalyst just got the normal Mac WKWebView but there appears to be differences.
Airplaying video doesn't seem to be working on Mac Catalyst (works on iOS). I'm on the same network.
Testing on Youtube. The "Airplay" button appears but clicking it does nothing. Anyone else experiencing this?
When playing a video in WKWebView I get this exception thrown after playing a video in "Full window mode" (that is when video takes over the size of the window, not to be confused with "full screen mode").
I'm running on Mac Catalyst.
#1 0x0000000188855800 in -[NSException raise] ()
#2 0x0000000189c2170c in -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] ()
#3 0x000000018968db9c in -[NSObject(NSKeyValueCoding) valueForKey:] ()
#4 0x000000018968da04 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#5 0x00000001b9709a10 in -[AVPlaybackControlsController _observeBoolForKeyPath:usingKeyValueObservationController:observationHandler:] ()
#6 0x00000001b97066a8 in -[AVPlaybackControlsController _startObservingForPlaybackViewUpdates] ()
#7 0x00000001b9708ad4 in -[AVPlaybackControlsController _updatePlaybackControlsVisibleAndObservingUpdates] ()
#8 0x00000001b96db568 in __81-[AVPlayerViewController transitionController:willBeginPresentingViewController:]_block_invoke ()
#9 0x00000001b290f3ec in -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] ()
#10 0x00000001b28e01cc in -[_UIViewControllerTransitionContext _runAlongsideCompletions] ()
#11 0x00000001b28df984 in -[_UIViewControllerTransitionContext completeTransition:] ()
#12 0x00000001b972300c in __35-[AVTransition completeTransition:]_block_invoke ()
#13 0x00000001b96da368 in -[AVPlayerViewController transitionController:transitionWillComplete:continueBlock:] ()
#14 0x00000001b9736448 in -[AVTransitionController transitionWillComplete:success:continueBlock:] ()
#15 0x00000001b9722e44 in -[AVTransition completeTransition:] ()
#16 0x00000001b2b08a04 in -[UIViewPropertyAnimator _executeCompletionHandlerWithFinalPosition:] ()
#17 0x00000001b2b08ac4 in -[UIViewPropertyAnimator _runCompletions:finished:] ()
#18 0x00000001b2b07b10 in __61-[UIViewPropertyAnimator _setupAssociatedViewAnimationState:]_block_invoke ()
#19 0x00000001b375214c in UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK ()
#20 0x00000001b28e2258 in -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] ()
#21 0x00000001b28e1d8c in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
#22 0x00000001b297c330 in -[UIViewAnimationState animationDidStop:finished:] ()
#23 0x0000000213b66110 in -[UIViewAnimationStateAccessibility animationDidStop:finished:] ()
#24 0x000000018fe7e288 in CA::Layer::run_animation_callbacks(void*) ()
And the exception is: "[<WebAVPlayerController valueForUndefinedKey:]: this class is not key value coding-compliant for the key coordinatedPlaybackActive."**
I configured a WKWebView to support full screen elements like this:
WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc]init];
WKPreferences *prefs = [[WKPreferences alloc]init];
prefs.elementFullscreenEnabled = YES;
webViewConfig.preferences = prefs;
//Create a WKWebView with the configuration and load a url like Youtube that supports playing videos in full screen....
Then I run the app and play a YouTube video. I enter full screen. Then I exit full screen and I hit an Autolayout crash.
0 libobjc.A.dylib 0x188365820 objc_msgSend + 32
1 CoreAutoLayout 0x1904ed82c -[NSLayoutConstraint _layoutEngine] + 36
2 CoreAutoLayout 0x1904ee3c0 __55+[NSLayoutConstraint _addOrRemoveConstraints:activate:]_block_invoke + 160
3 CoreAutoLayout 0x1904d4514 -[NSISEngine withBehaviors:performModifications:] + 88
4 CoreAutoLayout 0x1904ee238 +[NSLayoutConstraint _addOrRemoveConstraints:activate:] + 308
5 WebKit 0x1a82777fc -[WKFullScreenWindowController finishedExitFullScreenAnimationAndExitImmediately:] + 936
6 WebKit 0x1a7d63868 -[WKFullScreenWindowController windowDidExitFullScreen:] + 44
7 CoreFoundation 0x1887a6560 CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 148
8 CoreFoundation 0x188844044 ___CFXRegistrationPost_block_invoke + 88
9 CoreFoundation 0x188843f8c _CFXRegistrationPost + 440
10 CoreFoundation 0x188777b64 _CFXNotificationPost + 708
11 Foundation 0x18966738c -[NSNotificationCenter postNotificationName:object:userInfo:] + 88
12 AppKit 0x18c4a3210 -[NSWindow(NSFullScreen) _didExitFullScreen] + 336
13 AppKit 0x18c2aa3ac -[_NSExitFullScreenTransitionController _doAfterExitFullScreen] + 304
14 AppKit 0x18c2acb28 ___NSRunLoopTimerCreateWithHandler_block_invoke + 56
15 CoreFoundation 0x1887cb54c CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 32
16 CoreFoundation 0x1887cb1f4 __CFRunLoopDoTimer + 940
17 CoreFoundation 0x1887cad4c __CFRunLoopDoTimers + 356
18 CoreFoundation 0x1887b0734 __CFRunLoopRun + 1896
19 CoreFoundation 0x1887af878 CFRunLoopRunSpecific + 612
20 HIToolbox 0x191e8ffa0 RunCurrentEventLoopInMode + 292
21 HIToolbox 0x191e8fde4 ReceiveNextEventCommon + 672
22 HIToolbox 0x191e8fb2c _BlockUntilNextEventMatchingListInModeWithFilter + 72
23 AppKit 0x18ba3584c _DPSNextEvent + 632
24 AppKit 0x18ba349dc -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 728
25 AppKit 0x18ba28e0c -[NSApplication run] + 464
26 AppKit 0x18ba00250 NSApplicationMain + 880
27 AppKitWKWebviewProjectForWebInspector 0x102fbbf80 main + 44 (main.m:14)
28 dyld 0x1883a7e50 start + 2544
Setting elementFullscreenEnabled property to YES on WKPreferences is not honored on Mac Catalyst.
WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc]init];
WKPreferences *prefs = [[WKPreferences alloc]init];
prefs.elementFullscreenEnabled = YES;
webViewConfig.preferences = prefs;
//then create the WKWebView..
I load a Youtube url in the WKWebView. Youtube complains that the browser doesn't support full screen. Is there a workaround?
Full screen does work in an AppKit app though using the exact same API...though it causes an Autolayout crash (I will be making another thread about that separate issue shortly).
I'm getting some new behavior I haven't seen before (on Venture 13.2.1) on UITableView.
Steps to reproduce:
A table view row is selected and I swipe to delete the selected row.
After about a half of a second the table view selects another row.
I'm not programmatically making a selection here after the swipe to delete. UIKit is doing it.
I set a breakpoint in -tableView:didSelectRowAtIndexPath: and it is related to the focus system:
#1 0x00000001b350b140 in -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:deselectPrevious:performCustomSelectionAction:] ()
#2 0x00000001b3512df8 in -[UITableView _didUpdateFocusInContext:withAnimationCoordinator:] ()
#3 0x0000000213b38988 in -[UITableViewAccessibility _didUpdateFocusInContext:withAnimationCoordinator:] ()
#4 0x00000001b2f54260 in __84-[UIFocusSystem _sendDidUpdateFocusNotificationsInContext:withAnimationCoordinator:]_block_invoke ()
#5 0x00000001b2f08944 in _UIFocusEnvironmentEnumerateAncestorEnvironments ()
#6 0x00000001b2f54480 in -[UIFocusSystem _sendNotificationsForFocusUpdateInContext:withAnimationCoordinator:usingBlock:] ()
#7 0x00000001b2f53ff0 in -[UIFocusSystem _sendDidUpdateFocusNotificationsInContext:withAnimationCoordinator:] ()
#8 0x00000001b2f53630 in -[UIFocusSystem _updateFocusWithContext:report:] ()
#9 0x00000001b2f5319c in -[UIFocusSystem updateFocusIfNeeded] ()
#10 0x00000001b2f561dc in __43-[UIFocusSystem _updateFocusUpdateThrottle]_block_invoke ()
#11 0x00000001b3725e70 in -[_UIAfterCACommitBlock run] ()
#12 0x00000001b37262cc in -[_UIAfterCACommitQueue flush] ()
#13 0x00000001b2851630 in _runAfterCACommitDeferredBlocks ()
#14 0x00000001b28513ac in _cleanUpAfterCAFlushAndRunDeferredBlocks ()
#15 0x00000001b28512c8 in _afterCACommitHandler ()
#16 0x00000001887b0db8 in CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION ()
#17 0x00000001887b0ca4 in __CFRunLoopDoObservers ()
This wasn't happening before. I'm not sure if it is related to the Ventura 13.2.1 update or if there is some minor tweak on my end that is causing this change in behavior though I'm not thrilling with UIKit making a selection without asking me about it.
I could live with the automatic row selection if the next row below the deleted row was automatically selected but sometimes it is not. Sometimes UITableView is auto selecting a row two cells back which doesn't make any sense to me.
My configuration:
A iOS app that supports Mac Catalyst. This Mac Catalyst app is “optimized for Mac” it is not scaled to match iPad.
I open the asset catalog and add a “Data Asset” which is a .txt file. This is set to “Universal.”
I add “Mac” variant for this data asset and I add a .txt with different text.
I load the string at runtime like this:
NSDataAsset *scriptData = [[NSDataAsset alloc]initWithName:@"TextDataAsset"];
NSString *loadedText = [[NSString alloc]initWithData:scriptData.data encoding:NSUTF8StringEncoding];
When I run that on Mac Catalyst the text loadedText is an empty string, which is wrong. Running on iOS I get the expected string.
Is this the intended behavior? Am I supposed to use the "iPad" device for Mac assets (because I don't believe that is the case with images, etc.)
In any case I filed FB12005255
I'm trying to enable the web inspector on WKWebView in a Mac Catalyst app. I'm only doing this for debugging purposes. In the released the web inspector will not be enabled.
Doing this under Mac Catalyst does not work:
WKPreferences *prefs = [[WKPreferences alloc]init];
[prefs _setDeveloperExtrasEnabled:YES];
//Assign the WKPreferences to a WKWebViewConfiguration and create the web view..
Is there any way to do this?
Thanks in advance.
I have an area in my app where I load local HTML strings in WKWebView. Loading is fast on iOS. These local HTML strings are small.
On Mac Catalyst I added the ability to open this area of the UI in a new window scene (new window). And for some reason sometimes when I do this these simple HTML strings can take 10-15 seconds to load in the WKWebview in the new window.
These HTML strings are super small. I key value observed the loading property of the WKWebview and I hold the current date just before calling -loadHTMLString:baseURL:
Then when the web view completes loading I see how much time passed:
-(void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id>*)change
context:(void*)context
{
if (object == self.webview
&& [keyPath isEqualToString:@"loading"])
{
if (!self.webview.isLoading)
{
NSTimeInterval timeInterval = [NSDate.date timeIntervalSinceDate:self.loadStartDate];
NSLog(@"Web view took %f seconds to load",timeInterval);
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Sometimes it is taking as long as 5 seconds to load a tiny HTML string. When opening these WKWebviews in the same window I don't get these long load times. But when I kick of WKWebView inside a new window scene I often do.